package com.edu.learning.concurrent.sample.mode2;

import java.time.Duration;
import java.time.LocalTime;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;

/**
 * @author ll
 * @Date 2017/10/25 17:17
 */
public class RecursiveActionDemo {

    private final static int NUMBER = 10000000;

    public static void main(String[] args) {
        double[] array = new double[NUMBER];
        for (int i = 0; i < NUMBER; i ++) {
            array[i] = i;
        }
        LocalTime start = LocalTime.now();
        System.out.println(LocalTime.now() + "\t >>> \t" + Runtime.getRuntime().availableProcessors());
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        forkJoinPool.invoke(new TestTask(array, 0, array.length));
        LocalTime end = LocalTime.now();
        System.out.println("Time span = " + Duration.between(start, end));//Time span = PT4.684S
    }


    private static class TestTask extends RecursiveAction {
        final double[] array;
        final int lo, hi;

        public TestTask(double[] array, int lo, int hi) {
            this.array = array;
            this.lo = lo;
            this.hi = hi;
        }

        @Override
        protected void compute() {
            if (hi - lo < 2) {
                for (int i = lo; i < hi; ++ i) {
                    array[i] = Math.sin(array[i]) + Math.cos(array[i]) + Math.tan(array[i]);
                }
            } else {
                int mid = (lo + hi) >>> 1;
                invokeAll(new TestTask(array, lo, mid), new TestTask(array, mid, hi));
            }
        }
    }
}
